# these next few lines import some of the WMP functions we will
# use in this file.
from backend.backend import Backend
from workflow.task import Task
from workflow.result import Result 
from workflow.flowData import Status

class GroceryBackendNew(Backend):
    
    def __init__(self): 
        # Specify the workflow name:       
        Backend.__init__(self, "GroceryStoreNew")
        
    def wire(self):
        # register the unload cart step
        self.register_result_listener("CustomerNew", "UnloadCart", self.cart_unloaded)
        # register the scan member card and scan groceries step 
        self.register_result_listener("CashierNew", "Scan", self.scan_complete)
        #register the bag groceries step
        self.register_result_listener("BaggerNew", "Bag", self.bag_complete)
        #register the fill cart step
        #self.register_result_listener("Bagger", "FillCart", self.fill_cart_complete)
        # register the request payment Step
        self.register_result_listener("CashierNew", "RequestPayment", self.request_payment_complete)
        #register the pay Step
        self.register_result_listener("CustomerNew", "Pay", self.pay_complete)
        #register the give change and receipt Step
        #self.register_result_listener("Cashier", "GiveChange", self.give_change_complete)
        #register the leave store step
        self.workflow.register_joined_listener([("CashierNew", "GiveChange", Result), ("BaggerNew", "FillCart", Result)], self.leave_store_predicate, self.ready_to_leave_store)        
        self.register_result_listener("CustomerNew", "LeaveStore", self.left_store)
    
    def cart_unloaded(self, results):
        for result in results:  # repeat the following actions for each result
            # After unloading the cart, Cashier should scan, and Bagger should bag 
            task = Task.construct_from_result(result, "CashierNew", "Scan")
            self.workflow.add(task) # add the new task to the workflow
            task = Task.construct_from_result(result, "BaggerNew", "Bag")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
            
    def scan_complete(self, results):
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below...
            task = Task.construct_from_result(result, "CashierNew", "RequestPayment")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
            
    def bag_complete(self, results):
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below...
            task = Task.construct_from_result(result, "BaggerNew", "FillCart")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
            
    def fill_cart_complete(self, results):
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below...
            self.workflow.update_status(result, Status.COMPLETE)
            
    def request_payment_complete(self, results):
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below...
            task = Task.construct_from_result(result, "CustomerNew", "Pay")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
            
    def pay_complete(self, results):
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below...
            task = Task.construct_from_result(result, "CashierNew", "GiveChange")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
    
    def give_change_complete(self, results):
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below...
            task = Task.construct_from_result(result, "CustomerNew", "LeaveStore")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
    
    # determines whether or not the listener should launch the left_store 
    def leave_store_predicate(self, results):
        FillCart = [result for result in results if result.stepname == "FillCart"];
        GiveChange = [result for result in results if result.stepname == "GiveChange"];
        return len(FillCart) == 1 and len(GiveChange) == 1
            
    def ready_to_leave_store(self, results):
        for result in results:
            self.workflow.update_status(result, Status.COMPLETE)
        copyFields =['FoundStuff'];
        appendFields = None;
        addFields = None;
        task = Task.construct_from_results(results, "CustomerNew", "LeaveStore", copy=copyFields, append=appendFields, add_fields=addFields);
        self.workflow.add(task);

            
    def left_store(self, results):
        for result in results:
            self.workflow.update_status(result, Status.COMPLETE)
            
if __name__ == '__main__':
    backend = GroceryBackendNew();